import { useEventListener } from "expo";
import { useAudioPlayer, useAudioPlayerStatus } from "expo-audio";
import * as FileSystem from "expo-file-system";
import { useLocalSearchParams, useRouter } from "expo-router";
import { useVideoPlayer, VideoPlayerStatus, VideoView } from "expo-video";
import React, { useEffect, useState } from "react";
import {
  ActivityIndicator,
  Alert,
  Button,
  Modal,
  Text,
  View,
} from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import AudioControls from "../components/AudioControls";
import Header from "../components/PlayerHeader";
import TranscriptList from "../components/TranscriptList";
import { SERVER_URL } from "../constants/Path";
import { RecordItem, Sentence, Transcription } from "../constants/types";

const TranscriptionButton: React.FC<{
  item: RecordItem;
  onTranscriptionUpdate: (result: Transcription | null) => void;
}> = ({ item, onTranscriptionUpdate }) => {
  const [loading, setLoading] = useState(false);

  const transcribeFile = async () => {
    setLoading(true);
    const dummyFile = { uri: item.uri, type: item.mimeType, name: item.name };
    const formData = new FormData();
    formData.append("file", dummyFile as any);
    try {
      const response = await fetch(SERVER_URL + "/transcribe", {
        method: "POST",
        body: formData,
      });
      const data = await response.json();
      setLoading(false);
      if (data.status === "success") {
        const DATA_FILE = FileSystem.documentDirectory + `/${item.id}.json`;
        await FileSystem.writeAsStringAsync(
          DATA_FILE,
          JSON.stringify(data.results)
        );
        Alert.alert("转录成功");
        onTranscriptionUpdate(data.results);
      } else {
        Alert.alert("转录失败");
      }
      setLoading(false);
    } catch (error) {
      Alert.alert("转录失败");
      console.log(error);
      setLoading(false);
    }
  };

  return (
    <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
      <Text
        style={{
          marginTop: -250,
          marginBottom: 10,
          fontSize: 24,
          color: "#666",
        }}
      >
        没有字幕？
      </Text>
      <Button title="开始AI转录" onPress={transcribeFile} disabled={loading} />
      <Modal visible={loading} transparent={true} animationType="fade">
        <View
          style={{
            flex: 1,
            justifyContent: "center",
            alignItems: "center",
            backgroundColor: "rgba(0,0,0,0.5)",
          }}
        >
          <View
            style={{
              height: 100,
              width: 150,
              backgroundColor: "#fff",
              borderRadius: 10,
              justifyContent: "center",
              alignItems: "center",
            }}
          >
            <ActivityIndicator size="large" />
            <Text style={{ marginTop: 10 }}>正在转录</Text>
          </View>
        </View>
      </Modal>
    </View>
  );
};

const VidoePlayer = ({ item }: { item: RecordItem }) => {
  const [loading, setLoading] = useState(false)
  const [transcript, setTranscript] = useState<Transcription | null>(null);

  const player = useVideoPlayer(item.uri, (player) => {
    player.timeUpdateEventInterval = 1;
  });

  const [playerStatus, setPlayerStatus] = useState<VideoPlayerStatus>(player.status);
  const [isPlaying, setIsPlaying] = useState<boolean>(player.playing);
  const [currentTime, setCurrentTime] = useState<number>(player.currentTime);

  useEventListener(player, "timeUpdate", ({ currentTime }) => {
    setCurrentTime(currentTime);
  });
  useEventListener(player, "playingChange", ({ isPlaying }) => {
    setIsPlaying(isPlaying);
  });

  useEventListener(player, "statusChange", ({ status }) => {
    setPlayerStatus(status);
  });

  const togglePlayPause = () => {
    if (playerStatus === "idle") {
      Alert.alert("视频正在加载");
      return;
    }
    if (isPlaying) {
      player.pause();
    } else {
      if (player.currentTime === player.duration) {
        player.currentTime = 0;
      }
      player.play();
    }
  };

  const handleSeek = (position: number) => {
    if (playerStatus === "idle") {
      Alert.alert("视频正在加载");
      return;
    }
    player.currentTime = position;
  };

  const handleActive = async (sentence: Sentence) => {
    if (sentence.translation) {
      return;
    }
    try {
      const response = await fetch(SERVER_URL + "/translate", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ text: sentence.text }),
      });
      const data = await response.json();
      const translation: string = data.translation || "翻译失败";

      const newTranscript = transcript?.map((stc) =>
        stc.id === sentence.id ? { ...stc, translation } : stc
      ) as Transcription;
      //更新到本地
      const DATA_FILE = FileSystem.documentDirectory + `/${item.id}.json`;
      await FileSystem.writeAsStringAsync(
        DATA_FILE,
        JSON.stringify(newTranscript)
      );
      setTranscript(newTranscript);
    } catch (error) {
      console.error("翻译错误:", error);
      const translation: string = "翻译服务不可用";
      const newTranscript = transcript?.map((stc) =>
        stc.id === sentence.id ? { ...stc, translation } : stc
      ) as Transcription;
      setTranscript(newTranscript);
    }
  }

  useEffect(() => {
    loadTranscript(item.id)
      .then((result) => {
        setTranscript(result);
        setLoading(false);
      })
      .catch((e) => {
        console.log(e);
      });
  }, []);

  return (
    <>
      <VideoView
        player={player}
        nativeControls={false}
        style={{
          width: "auto",
          height: 200,
          margin: 10,
          borderRadius: 16,
          backgroundColor: "#000",
        }}
      />
      {loading ? null : transcript === null ? (
        <TranscriptionButton
          item={item}
          onTranscriptionUpdate={setTranscript}
        />
      ) : (
        <TranscriptList
          data={transcript}
          currentTime={currentTime}
          onPress={handleSeek}
          onActive={handleActive}
        />
      )}
      <AudioControls
        isPlaying={isPlaying}
        onPlayPause={togglePlayPause}
        position={currentTime}
        duration={player.duration}
        onSeek={handleSeek}
      />
    </>
  );
};

const AudioPlayer = ({ item }: { item: RecordItem }) => {
  const [loading, setLoading] = useState(true);
  const [transcript, setTranscript] = useState<Transcription | null>(null);

  const player = useAudioPlayer(item.uri);
  const playerStatus = useAudioPlayerStatus(player);

  const togglePlayPause = () => {
    if(!player.isLoaded){
      Alert.alert("音频正在加载");
      return;
    }
    if (player.playing) {
      player.pause();
    } else {
      if (playerStatus.didJustFinish) {
        player.seekTo(0);
      }
      player.play();
    }
  };

  const handleSeek = (position: number) => {
    if(!player.isLoaded){
      Alert.alert("音频正在加载");
      return;
    }
    player.seekTo(position);
  };

  const handleActive = async (sentence: Sentence) => {
    if (sentence.translation) {
      return;
    }
    try {
      const response = await fetch(SERVER_URL + "/translate", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ text: sentence.text }),
      });
      const data = await response.json();
      const translation: string = data.translation || "翻译失败";

      const newTranscript = transcript?.map((stc) =>
        stc.id === sentence.id ? { ...stc, translation } : stc
      ) as Transcription;
      //更新到本地
      const DATA_FILE = FileSystem.documentDirectory + `/${item.id}.json`;
      await FileSystem.writeAsStringAsync(
        DATA_FILE,
        JSON.stringify(newTranscript)
      );
      setTranscript(newTranscript);
    } catch (error) {
      console.error("翻译错误:", error);
      const translation: string = "翻译服务不可用";
      const newTranscript = transcript?.map((stc) =>
        stc.id === sentence.id ? { ...stc, translation } : stc
      ) as Transcription;
      setTranscript(newTranscript);
    }
  };
  useEffect(() => {
    loadTranscript(item.id)
      .then((result) => {
        setTranscript(result);
        setLoading(false);
      })
      .catch((e) => {
        console.log(e);
      });
  }, []);

  return (
    <>
      {loading ? (
        <ActivityIndicator />
      ) : transcript === null ? (
        <TranscriptionButton item={item} onTranscriptionUpdate={setTranscript} />
      ) : (
        <TranscriptList
          data={transcript}
          currentTime={playerStatus.currentTime}
          onPress={handleSeek}
          onActive={handleActive}
        />
      )}

      <AudioControls
        isPlaying={playerStatus.playing && !playerStatus.didJustFinish}
        onPlayPause={togglePlayPause}
        position={playerStatus.currentTime}
        duration={playerStatus.duration}
        onSeek={handleSeek}
      />
    </>
  );
};

const loadTranscript = async (id:string):Promise<Transcription | null> => {
  return new Promise(async (resolve, reject) => {
  try {
    const DATA_FILE = FileSystem.documentDirectory + `/${id}.json`;
    const info = await FileSystem.getInfoAsync(DATA_FILE);
    if (info.exists) {
      const content = await FileSystem.readAsStringAsync(DATA_FILE);
      resolve(JSON.parse(content));
    }else{
      resolve(null);
    }
  } catch (e) {
    reject(e);
  }
  })
};
export default function PlayerScreen() {
  const router = useRouter();
  const insets = useSafeAreaInsets();
  const params = useLocalSearchParams() as unknown as RecordItem;

  return (
    <View style={{ flex: 1, paddingTop: insets.top }}>
      <Header
        name={params?.name}
        onBack={() => router.back()}
        onSearch={() => router.push({ pathname: "/search" })}
      />
      {params.type === "video" ? (
        <VidoePlayer item={params}/>
      ) : (
        <AudioPlayer item={params}/>
      )}
    </View>
  );
}
